#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

// 定义火车信息结构体
typedef struct Train {
    char number[20];       // 车次
    char start[20];       // 始发站
    char end[20];         // 终点站
    char startTime[20];   // 始发时间
    char endTime[20];     // 到达时间
    float price;          // 票价
    int tickets;          // 剩余票数
    struct Train* next;   // 指向下一个节点的指针
} Train;

// 定义订票信息结构体
typedef struct Booking {
    char trainNumber[20]; // 车次
    char username[20];    // 姓名
    char idCard[18];      // 身份证号
    struct Booking* next; // 指向下一个节点的指针
} Booking;

Train* head = NULL;       // 火车信息链表头指针
Booking* bookHead = NULL; // 订票信息链表头指针

// 添加火车信息模块
void addTrainInfo() {
    Train* newTrain = (Train*)malloc(sizeof(Train));
    printf("请输入车次：");
    scanf("%s", newTrain->number);

    // 检查车次是否已存在
    Train* temp = head;
    while (temp != NULL) {
        if (strcmp(temp->number, newTrain->number) == 0) {
            printf("该车次已存在！\n");
            free(newTrain);
            system("pause");
            return;
        }
        temp = temp->next;
    }

    printf("请输入始发站：");
    scanf("%s", newTrain->start);
    printf("请输入终点站：");
    scanf("%s", newTrain->end);
    printf("请输入始发时间（HH:MM）：");
    scanf("%s", newTrain->startTime);
    printf("请输入到达时间（HH:MM）：");
    scanf("%s", newTrain->endTime);
    printf("请输入票价：");
    scanf("%f", &newTrain->price);
    printf("请输入剩余票数：");
    scanf("%d", &newTrain->tickets);

    newTrain->next = head;
    head = newTrain;
    printf("车次添加成功！\n");
    system("pause");
}

// 根据车次查询火车信息
Train* searchByNumber(char* number) {
    Train* temp = head;
    while (temp != NULL) {
        if (strcmp(temp->number, number) == 0) {
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}

// 根据城市查询火车信息
void searchByCity(char* city) {
    Train* temp = head;
    int found = 0;
    printf("查询结果：\n");
    while (temp != NULL) {
        if (strcmp(temp->start, city) == 0 || strcmp(temp->end, city) == 0) {
            printf("车次：%s\t始发站：%s\t终点站：%s\t时间：%s-%s\t票价：%.2f\t余票：%d\n",
                   temp->number, temp->start, temp->end,
                   temp->startTime, temp->endTime, temp->price, temp->tickets);
            found = 1;
        }
        temp = temp->next;
    }
    if (!found) printf("没有找到相关车次\n");
    
}

// 查询模块
void searchTrain() {
    int choice;
    printf("请选择查询方式：1-按车次 2-按城市\n");
    scanf("%d", &choice);
    if (choice == 1) {
        char number[20];
        printf("请输入车次：");
        scanf("%s", number);
        Train* train = searchByNumber(number);
        if (train != NULL) {
            printf("车次：%s\t始发站：%s\t终点站：%s\t时间：%s-%s\t票价：%.2f\t余票：%d\n",
                   train->number, train->start, train->end,
                   train->startTime, train->endTime, train->price, train->tickets);
            system("pause");
        } else {
            printf("该车次不存在！\n");
            system("pause");
        }
    } else if (choice == 2) {
        char city[20];
        printf("请输入城市：");
        scanf("%s", city);
        searchByCity(city);
        system("pause");
    } else {
        printf("无效选择！\n");
        system("pause");
    }
}

// 订票模块
void bookTicket() {
    char city[20];
    printf("请输入目的地城市：");
    scanf("%s", city);
    searchByCity(city); // 先显示符合条件的车次

    char number[20];
    printf("请选择要预订的车次（输入车次编号）：");
    scanf("%s", number);
    Train* train = searchByNumber(number);
    if (train == NULL || train->tickets <= 0) {
        printf("该车次不可预订！\n");
        system("pause");
        return;
    }

    // 创建订票信息
    Booking* newBooking = (Booking*)malloc(sizeof(Booking));
    strcpy(newBooking->trainNumber, number);
    printf("请输入姓名：");
    scanf("%s", newBooking->username);
    printf("请输入身份证号：");
    scanf("%s", newBooking->idCard);

    newBooking->next = bookHead;
    bookHead = newBooking;

    // 更新余票
    train->tickets--;
    printf("订票成功！剩余票数：%d\n", train->tickets);
    system("pause");
}

// 修改模块
void modifyTrain() {
    char number[20];
    printf("请输入要修改的车次：");
    scanf("%s", number);
    Train* train = searchByNumber(number);
    if (train == NULL) {
        printf("该车次不存在！\n");
        system("pause");
        return;
    }

    printf("当前车次信息：\n");
    printf("始发站：%s\t终点站：%s\t票价：%.2f\t余票：%d\n",
           train->start, train->end, train->price, train->tickets);

    printf("请输入新的始发站：");
    char temp[20];
    scanf("%s", temp);
    if (strlen(temp) > 0) strcpy(train->start, temp);

    printf("请输入新的终点站：");
    scanf("%s", temp);
    if (strlen(temp) > 0) strcpy(train->end, temp);

    printf("请输入新的票价：");
    if (scanf("%f", &train->price) == 0) {
        scanf("%*s"); // 清除输入缓冲区
    }

    printf("修改成功！\n");
    system("pause");
}

// 显示模块
void showTrainInfo() {
    Train* temp = head;
    if (temp == NULL) {
        printf("当前没有车次信息\n");
        system("pause");
        return;
    }
    printf("所有车次信息：\n");
    while (temp != NULL) {
        printf("车次：%s\t始发站：%s\t终点站：%s\t时间：%s-%s\t票价：%.2f\t余票：%d\n",
               temp->number, temp->start, temp->end,
               temp->startTime, temp->endTime, temp->price, temp->tickets);
        temp = temp->next;
    }
    system("pause");
}

// 保存模块（火车信息和订票信息分别保存）
void saveTrainInfo() {
    FILE* fp = fopen("trains.dat", "wb");
    if (fp == NULL) {
        printf("无法打开文件！\n");
        system("pause");
        return;
    }
    Train* temp = head;
    while (temp != NULL) {
        fwrite(temp, sizeof(Train), 1, fp);
        temp = temp->next;
    }
    fclose(fp);
    printf("火车信息已保存\n");
    system("pause");
}

void saveBookingInfo() {
    FILE* fp = fopen("bookings.dat", "wb");
    if (fp == NULL) {
        printf("无法打开文件！\n");
        return;
    }
    Booking* temp = bookHead;
    while (temp != NULL) {
        fwrite(temp, sizeof(Booking), 1, fp);
        temp = temp->next;
    }
    fclose(fp);
    printf("订票信息已保存\n");
}

void saveAll() {
    saveTrainInfo();
    saveBookingInfo();
}

// 从文件加载数据
void loadTrainInfo() {
    FILE* fp = fopen("trains.dat", "rb");
    if (fp == NULL) return; // 文件不存在时直接返回
	//链表实现车次信息存储
    Train* temp;
    while (1) {
        temp = (Train*)malloc(sizeof(Train));
        if (fread(temp, sizeof(Train), 1, fp) != 1) {
            free(temp);
            break;
        }
        temp->next = head;
        head = temp;
    }
    fclose(fp);
}

void loadBookingInfo() {
    FILE* fp = fopen("bookings.dat", "rb");
    if (fp == NULL) return;
	//一切注释同loadTrainInfo函数
    Booking* temp;
    while (1) {
        temp = (Booking*)malloc(sizeof(Booking));
        if (fread(temp, sizeof(Booking), 1, fp) != 1) {
            free(temp);
            break;
        }
        temp->next = bookHead;
        bookHead = temp;
    }
    fclose(fp);
}

// 主菜单
void menu() {
    printf("\n===== 火车票订票系统 =====\n");
    printf("1. 添加车次信息\n");
    printf("2. 查询车次信息\n");
    printf("3. 预订车票\n");
    printf("4. 修改车次信息\n");
    printf("5. 显示所有车次\n");
    printf("6. 保存所有信息\n");
    printf("0. 退出系统\n");
    printf("tips：退出系统前请记得保存信息哦~\n");
    printf("请选择操作：");
}

int main() {
    int choice;
    // 加载历史数据
    loadTrainInfo();
    loadBookingInfo();

    do {
    	system("cls");
        menu();//打印主界面
        scanf("%d", &choice);//对选择模式进行录入
        switch (choice) {
            case 1:
                addTrainInfo();
                break;
            case 2:
                searchTrain();
                break;
            case 3:
                bookTicket();
                break;
            case 4:
                modifyTrain();
                break;
            case 5:
                showTrainInfo();
                break;
            case 6:
                saveAll();
                break;
            case 0:
                printf("感谢使用！\n");
                break;
            default:
                printf("无效选择，请重新输入！\n");
        }
    } while (choice != 0);

// 释放火车信息链表内存
	    Train* trainTemp;
	    while (head != NULL) {
	        trainTemp = head;
	        head = head->next;
	        free(trainTemp);
	    }
	
// 释放订票信息链表内存
	Booking* bookingTemp;
	while (bookHead != NULL) {
	    bookingTemp = bookHead;
    	bookHead = bookHead->next;
	    free(bookingTemp);
	}
	
    return 0;
}